package cn.chengpengper.shortlink.util;

import cn.chengpengper.shortlink.constant.ShortLinkConstant;
import cn.chengpengper.shortlink.model.LoginUser;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import lombok.extern.slf4j.Slf4j;

import java.time.LocalDate;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.Date;
import java.util.Objects;

/**
 * @author huchengpeng
 * @version v1.0.0
 * @date 2023/8/22 23:43
 * @description JWT 工具类
 */
@Slf4j
public class JwtUtil {

    /**
     * 主题
     */
    private static final String SUBJECT = "short-link";

    /**
     * 加密密钥
     */
    private static final String SECRET = "Y7wHaK8iYsOZGFv3ypR4";

    /**
     * 令牌前缀
     */
    private static final String TOKEN_PREFIX = "short-link-token:";

    /**
     * 过期时间
     */
    private static final Long EXPIRED = 1000 * 3600 * 2L;

    public static final String HEAD_IMG = "head_img";
    public static final String ACCOUNT_NO = "account_no";
    public static final String USERNAME = "username";
    public static final String MAIL = "mail";
    public static final String PHONE = "phone";
    public static final String AUTH = "auth";

    /**
     * <p>
     * 根据登录用户生成JsonWebToken
     * </p>
     *
     * @param user 登录用户
     * @return String
     */
    public static String genJsonWebToken(LoginUser user) {
        if (Objects.isNull(user)) {
            throw new NullPointerException("对象为空");
        }

        LocalDate expireTime = LocalDate.now().plus(EXPIRED, ChronoUnit.MILLIS);

        String token = Jwts.builder()
                .setSubject(SUBJECT)
                .claim(HEAD_IMG, user.getHeadImg())
                .claim(ACCOUNT_NO, user.getAccountNo())
                .claim(USERNAME, user.getUsername())
                .claim(MAIL, user.getMail())
                .claim(PHONE, user.getPhone())
                .claim(AUTH, user.getAuth())
                .setIssuedAt(CommonUtil.now())
                .setExpiration(Date.from(expireTime.atStartOfDay(ZoneId.systemDefault()).toInstant()))
                .signWith(SignatureAlgorithm.HS256, SECRET)
                .compact();

        token = TOKEN_PREFIX + token;
        return token;
    }

    /**
     * <p>
     * 解密JsonWebToken
     * </p>
     *
     * @param token 待解密的Jwt
     * @return Claims
     */
    public static Claims decryptJsonWebToken(String token) {
        try {
            return Jwts.parser()
                    .setSigningKey(SECRET)
                    .parseClaimsJws(token.replace(TOKEN_PREFIX, ShortLinkConstant.BLANK))
                    .getBody();
        } catch (Exception e) {
            log.error("JwtUtil | decryptJsonWebToken | Has a exception:", e);
            return null;
        }
    }

}
